/*
* License:  This  program  is  free  software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as published by
* the  Free Software Foundation; either version 3 of the License, or (at your
* option)  any later version. This program is distributed in the hope that it
* will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
* Public License for more details.
*/

package pcgen.CharacterViewer.resources;

import org.json.JSONException;
import org.json.JSONObject;

import android.os.Parcel;
import android.os.Parcelable;

import pcgen.android.Logger;

public class GameResourceAttributeAbility extends GameResourceAttribute
{
	public GameResourceAttributeAbility()
	{	
		setType(Types.Ability);
	}
	
	public GameResourceAttributeAbility(Parcel in)
	{
		super(in);
		setType(Types.Ability);
	}
	
	public static final Parcelable.Creator<GameResourceAttributeAbility> CREATOR = new Parcelable.Creator<GameResourceAttributeAbility>() 
	{
		public GameResourceAttributeAbility createFromParcel(Parcel in) 
		{
		    return new GameResourceAttributeAbility(in);
		}
		
		public GameResourceAttributeAbility[] newArray(int size) 
		{
		    return new GameResourceAttributeAbility[size];
		}
	};
	
	@Override
	public void addModifier(GameResourceModifier modifier)
	{
		super.addModifier(modifier);
		
		onValueModified();
	}
	
	public int getAbilityModifier()
	{
		int ability = getValue();
	
		if (ability < 10)
			return new Double(Math.ceil((10 - ability) / 2)).intValue() * -1;

		return new Double(Math.floor((ability - 10) / 2)).intValue();
	}
	
	@Override
	public int getModifier()
	{
		int value = super.getModifier();
		value = checkStatus(value);
		return value;
	}
	
	@Override
	public int getValue()
	{
		int value = getValueBase() + getModifier() + getMisc();
		
		//value = checkStatus(value);
		
		// If the value is less than the min., return the min. value instead.
		if (value < getValueMin())
			return getValueMin();
		
		return value;
	}
	
	protected int checkStatus(int value)
	{
		if (isTypeStrength())
		{
			if (getCharacter().hasCondition(GameTypesCondition.Fatigued))
				value -= 2;
			else if (getCharacter().hasCondition(GameTypesCondition.Exhausted))
				value -= 6;
			
			if (getCharacter().hasCondition(GameTypesCondition.Paralyzed) ||
				getCharacter().hasCondition(GameTypesCondition.Petrified))
				return 0;
		}
		else if (isTypeDexterity())
		{
			if (getCharacter().hasCondition(GameTypesCondition.Fatigued))
				value -= 2;
			else if (getCharacter().hasCondition(GameTypesCondition.Exhausted))
				value -= 6;
			
			if (getCharacter().hasCondition(GameTypesCondition.Entangled))
				value -= 4;
			
			if (getCharacter().hasCondition(GameTypesCondition.Paralyzed) ||
				getCharacter().hasCondition(GameTypesCondition.Petrified))
				return 0;
		}
		
		return value;
	}
	
	public int getValueOriginal()
	{
		return getValueBase() + getMisc();
	}
	
	public int getValueMax()
	{
		// This is the maximum value of the ability minus damage/healing modifiers.
		int value = getValueBase() + getModifierTemp() + getMisc();
		
		// If the value is less than the min., return the min. value instead.
		if (value < getValueMin())
			return getValueMin();
		
		return value;
	}
	
	public int getValueMaxDamage()
	{
		// Maximum damage is always the current value of the ability
		// without temporary or miscellaneous modifiers;
		// you can never take more damage that is currently available.
		int value = getValue() - getModifierTemp() - getMisc();
		
		// If the value is less than the min., return the min. value instead.
		if (value < getValueMin())
			return getValueMin();
		
		return value;
	}
	
	public int getValueMaxHeal()
	{
		int damageSustained = Math.abs(getModifierDamageAndHealing());
		int valueMax = getValue() - getModifierTemp() - getMisc();
		
		// If for whatever reason the damage taken minus the temporary and
		// miscellaneous modifiers is greater than the maximum value, then 
		// return the maximum value.
		if (damageSustained > valueMax)
			damageSustained = valueMax;
		
		return damageSustained;
	}
	
	public int getValueMin()
	{
		return 0;
	}
	
	public boolean isType(int type)
	{
		return getAbilityType() == type;
	}
	
	public boolean isTypeCharisma()
	{
		return isType(GameAbilities.Charisma);
	}
	
	public boolean isTypeConstitution()
	{
		return isType(GameAbilities.Constitution);
	}
	
	public boolean isTypeDexterity()
	{
		return isType(GameAbilities.Dexterity);
	}
	
	public boolean isTypeIntelligence()
	{
		return  isType(GameAbilities.Intelligence);
	}
	
	public boolean isTypeStrength()
	{
		return isType(GameAbilities.Strength);
	}
	
	public boolean isTypeWisdom()
	{
		return isType(GameAbilities.Wisdom);
	}
	
	@Override
	public JSONObject load(JSONObject data)
		throws JSONException
	{
		super.load(data);
		
		if (data == null)
			return null;
	    
	    return data;
	}
	
	public void modifyValueDamage(int value)
	{
		try
		{
			onValueModifiedIgnore = true;
			
			value = (value > 0 ? value * -1 : value);
		
			addModifier(GameResourceModifier.ModifierTypes.Damage, value);
		
			onValueModifiedIgnore = false;
			onValueModified();
		}
		finally
		{
			onValueModifiedIgnore = false;
		}
	}
	
	public void modifyValueHealing(int value)
	{
		try
		{
			value = (value > 0 ? value : value * -1);
				
			addModifier(GameResourceModifier.ModifierTypes.Healing, value);
		
			onValueModifiedIgnore = false;
			onValueModified();
		}
		finally
		{
			onValueModifiedIgnore = false;
		}
	}
	
	@Override
	public void onValueModified()
	{
		if (onValueModifiedIgnore)
			return;
		
		// If the value of the healing is greater than or equal to
		// the damage, then clean it out.
		removeDamageAndHealing();
		
		super.onValueModified();
	}
	
	@Override
	public void removeModifier(GameResourceModifier modifier)
	{
		super.removeModifier(modifier);
		
		onValueModified();
	}
	
	@Override
	public JSONObject save() 
		throws JSONException
	{
	    JSONObject data = super.save();
	    
	    return data;
	}

	private static final String TAG = GameResourceAttributeAbility.class.getSimpleName();
}
